package org.eerbaar.parser.grammers;

import org.eerbaar.parser.core.Grammar;
import org.eerbaar.parser.core.def.NonTerminal;
import org.eerbaar.parser.core.def.Symbol;
import org.eerbaar.parser.core.def.impl.DefaultGrammar;
import org.eerbaar.parser.core.def.impl.DefaultNonTerminal;
import org.eerbaar.parser.core.def.impl.DefaultTerminal;
import org.eerbaar.parser.core.exe.SymbolInstance;

/**
 * The grammar is a concrete implementation in Chomsky normal form (CNF) of a
 * context-free grammar ({@link Grammar}). CNF means that all non-terminal
 * productions ({@link NonTerminalProduction}) have the format A -&gt; B C, and
 * all terminal productions ({@link TerminalProduction}) have the format A -&gt;
 * b. The grammar has the following productions:
 * 
 * <ul>
 * <li>S NP VP</li>
 * <li>NP -&gt; Adj NP</li>
 * <li>NP -&gt; NP PP</li>
 * <li>NP -&gt; Det Noun</li>
 * <li>VP -&gt; Verb PP</li>
 * <li>VP -&gt; Verb NP</li>
 * <li>PP -&gt; Prep NP</li>
 * 
 * <li>Noun -&gt; time</li>
 * <li>NP -&gt; time</li>
 * <li>Adj -&gt; time</li>
 * <li>Verb -&gt; time</li>
 * <li>VP -&gt; time</li>
 * <li>Noun -&gt; flies</li>
 * <li>NP -&gt; flies</li>
 * <li>Verb -&gt; flies</li>
 * <li>VP -&gt; flies</li>
 * <li>Verb -&gt; like</li>
 * <li>VP -&gt; like</li>
 * <li>Prep -&gt; like</li>
 * <li>Det -&gt; an</li>
 * <li>Noun -&gt; arrow</li>
 * <li>NP -&gt; arrow</li>
 * </ul>
 * 
 * S is the start symbol, and the grammar recognises the sentence &quot;time
 * flies like an arrow&quot;.
 * 
 * @author Eva Forsbom
 * @author evafo@stp.lingfil.uu.se
 * @version 0.1
 * @version 2005-10-13
 * 
 */
public class TimeFliesGrammarCNF
    extends DefaultGrammar {

    /**
     * Creates a grammar in Chomsky normal form, for the sentence &quot;time
     * flies like an arrow&quot;.
     */
    public TimeFliesGrammarCNF() {
        super();
        createGrammar();
    }

    /*
     * (non-Javadoc)
     * 
     * @see parsing.Grammar#createGrammar()
     */
    public Grammar createGrammar() {
        // load grammar
        // create non-terminals
        NonTerminal s = new DefaultNonTerminal("S");
        NonTerminal np = new DefaultNonTerminal("NP");
        NonTerminal vp = new DefaultNonTerminal("VP");
        NonTerminal adj = new DefaultNonTerminal("Adj");
        NonTerminal noun = new DefaultNonTerminal("Noun");
        NonTerminal pp = new DefaultNonTerminal("PP");
        NonTerminal det = new DefaultNonTerminal("Det");
        NonTerminal verb = new DefaultNonTerminal("Verb");
        NonTerminal prep = new DefaultNonTerminal("Prep");

        // create terminals
        SymbolInstance time = new DefaultTerminal("time");
        SymbolInstance flies = new DefaultTerminal("flies");
        SymbolInstance like = new DefaultTerminal("like");
        SymbolInstance an = new DefaultTerminal("an");
        SymbolInstance arrow = new DefaultTerminal("arrow");

        // setStartSymbol(s);

        // S -> NP VP
        addNonTerminalProduction(s, new Symbol[] { np, vp });

        // NP -> Adj NP
        addNonTerminalProduction(np, new Symbol[] { adj, np });

        // NP -> NP PP
        addNonTerminalProduction(np, new Symbol[] { np, pp });

        // NP -> Det Noun
        addNonTerminalProduction(np, new Symbol[] { det, noun });

        // VP -> Verb PP
        addNonTerminalProduction(vp, new Symbol[] { verb, pp });

        // VP -> Verb NP
        addNonTerminalProduction(vp, new Symbol[] { verb, np });

        // PP -> Prep NP
        addNonTerminalProduction(pp, new Symbol[] { prep, np });

        // time : Noun, NP, Adj, Verb, VP
        addTerminalProduction(noun, time);
        addTerminalProduction(np, time);
        addTerminalProduction(adj, time);
        addTerminalProduction(verb, time);
        addTerminalProduction(vp, time);

        // flies : Noun, NP, Verb, VP
        addTerminalProduction(noun, flies);
        addTerminalProduction(np, flies);
        addTerminalProduction(verb, flies);
        addTerminalProduction(vp, flies);

        // like : Verb, VP, Prep
        addTerminalProduction(verb, like);
        addTerminalProduction(vp, like);
        addTerminalProduction(prep, like);

        // an : Det
        addTerminalProduction(det, an);

        // arrow : Noun, NP
        addTerminalProduction(noun, arrow);
        addTerminalProduction(np, arrow);

        return this;
    }

}